package com.haisen.controller;


import com.alibaba.fastjson.JSON;
import com.haisen.core.utils.PageResultSet;
import com.haisen.core.utils.Result;
import com.haisen.core.utils.ResultCodeEnum;
import com.haisen.dataobject.entity.UploadFile;
import com.haisen.dataobject.query.UploadFileQuery;
import com.haisen.exception.BizException;
import com.haisen.service.UploadFileService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.sql.ParameterMetaData;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 通用文件上出处理类
 */
@Controller
@RequestMapping("/fileserver")
@Slf4j
public class FileUploadController {


    @Value("${web.upload-path}")
    private String uploadFolder;

    @Value("${web.upload-url}")
    private String uploadUrl;
@Autowired
   private UploadFileService uploadFileService;

    @GetMapping
   // @RequiresPermissions("user:view")
    public String page(Model model) {
        return "system/uploadFile";
    }

    @ResponseBody
    @RequestMapping("/list")
    //@RequiresPermissions("user:view")
    public PageResultSet<UploadFile> list(UploadFileQuery uploadFileQuery) {
        if (uploadFileQuery == null){
            uploadFileQuery = new UploadFileQuery();
        }
        return uploadFileService.findByPage(uploadFileQuery);
    }

    /**
     * request包含了文件部分，直接JSON.toJSONString(request)会报错不支持异步方法
     * 增加获取request.getParameter可以获取其他非异步提交的参数
     * @param request
     * @return
     */
    @ResponseBody
    @PostMapping("/create")
    public Result create(HttpServletRequest request){

       // log.info("访问到了controller,{}",JSON.toJSONString(request.getParameter("uploadjson")));
        String mapJson = request.getParameter("uploadjson");
        uploadFileService.create(mapJson);
        return Result.success();
    }

    /**
     * 指定目录结构，不同模块图片存储不同文件夹中
     * @param request
     * @param response
     * @return
     */
    @ResponseBody
    @PostMapping("/upload")
    public Result uploadHeadImg(HttpServletRequest request, HttpServletResponse response){
        Map<String, Object> result = new HashMap<String, Object>();
        //调用通用接口上传文件，reportFile html input id
        result = uploadFile(request);
        //log.info("返回结果={}", JSON.toJSONString(result));
            //result != null &&
        if ( !result.isEmpty() && (Boolean) result.get("success"))
            return  Result.success(result.get("data"));
        else
            return Result.failure("703","存储文件失败");

    }

    /**
     * 上传文件通用接口
     *
     * @param request           请求体
     * */
    protected Map<String, Object> uploadFile(HttpServletRequest request) {
        Map<String, Object> ret = new HashMap<String, Object>();
        if (ServletFileUpload.isMultipartContent(request)) {
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            //id绑定的就是文件
            String inputId = multipartRequest.getParameter("inputId");
            //文件索引
            String previewId = multipartRequest.getParameter("previewId");
            String relativeDir = multipartRequest.getParameter("destDir");
            String saveDir = uploadFolder + relativeDir;
            log.info("控件Id：{},存储路径={}",inputId,saveDir);
            //建立保存目录
            mkdir(saveDir);
            List<MultipartFile> fileList = multipartRequest.getFiles(inputId);

            for (MultipartFile item : fileList) {
                String fileName = "";        //当前上传文件全名称
                String fileType = "";        //当前上传文件类型
                Integer fileSize =0;        //文件大小
                String newFileName = "";    //保存到服务器目录的文件名称
                String tagPathFile = "";   //存储路径+文件名
                String tagUrlPath = "";      //url访问路径+文件名
                try {
                    fileName = item.getOriginalFilename();
                    fileType = item.getContentType();
                    fileSize = (int)item.getSize();
                    //新文件名
                    newFileName = getCurrentTime("yyyyMMddHHmmss") + "_" + fileName;
                    //绝对路径
                    tagPathFile = saveDir + "/"+ newFileName;
                    tagPathFile = tagPathFile.replace("/", File.separator).replace("\\", File.separator);
                    tagUrlPath = uploadUrl+relativeDir+"/"+newFileName;
                    tagUrlPath = tagUrlPath.replace("/", File.separator).replace("\\", File.separator);
                    File savedFile = new File(saveDir, newFileName);
                    item.transferTo(savedFile);

                    //上传文件成功，保存文件信息到表reportDetail
                    Map<String, Object> param = new HashMap<String, Object>();
                    param.put("previewId",previewId);
                    param.put("sourceName", fileName);
                    param.put("sourceType", fileType);
                    param.put("sourceSize",fileSize);
                    param.put("tagPathFile", tagPathFile);
                    param.put("tagUrlPath",tagUrlPath);
                    param.put("createTime", getCurrentTime("yyyy-MM-dd HH:mm:ss"));
                    ret.put("success",true);
                    log.info("存储参数={}",JSON.toJSONString(param));
                    ret.put("data",JSON.toJSON(param));
                  log.info("---上传传文件处理成功，返回：{}",JSON.toJSONString(param));
                } catch (Exception e) {
                    log.error(e.getMessage());
                    ret.put("success", false);
                    throw  new BizException(e.getMessage());
                }
            }
        }
        return ret;
    }

    private String getCurrentTime(String dateFormat) {
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        return sdf.format(Calendar.getInstance().getTime());
    }

    private void mkdir(String dir){
        File fileUploadPath = new File(dir);
        if (!fileUploadPath.exists()) {
            //只建立了一级目录，多级结构不行
            //fileUploadPath.mkdir();
            try {
                FileUtils.forceMkdir(new File(dir));
            } catch (IOException e) {
                e.printStackTrace();
                throw new BizException(ResultCodeEnum.FAILED_UPLOAD_FILE_CREATE_DICTORY);
            }
        }
    }

}
